package com.company.Thread;

import cn.hutool.core.util.StrUtil;
import com.company.Main;

import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class ParallelMain {
    static int count = 64;

    public static void main(String[] args) throws InterruptedException {
        oom1();
        synchronizedClass sync = new synchronizedClass();
        Main.threadTest(6, item -> {
            if (item % 2 == 0) {
                try {
                    sync.testB(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                sync.testA(8);
            }
        });

    }

    static void oom1() throws InterruptedException {

        ThreadPoolExecutor threadPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(1);
       printStats(threadPool);
        for (int i = 0; i < 100000000; i++) {
            threadPool.execute(() -> {
                String payload = IntStream.rangeClosed(1, 1000000)
                        .mapToObj(__ -> "a")
                        .collect(Collectors.joining("")) + UUID.randomUUID().toString();
                System.out.println(Thread.currentThread());
                try {
                    TimeUnit.HOURS.sleep(1);
                } catch (InterruptedException e) {
                }
                System.out.println(payload);
            });
        }

        threadPool.shutdown();
        threadPool.awaitTermination(1, TimeUnit.HOURS);
    }

    static void printStats(ThreadPoolExecutor threadPool) {
        Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> {
            System.out.println("=========================");
            System.out.println(StrUtil.format("Pool Size: {}", threadPool.getPoolSize()));
            System.out.println(StrUtil.format("Active Threads: {}", threadPool.getActiveCount()));
            System.out.println(StrUtil.format("Number of Tasks Completed: {}", threadPool.getCompletedTaskCount()));
            System.out.println(StrUtil.format("Number of Tasks in Queue: {}", threadPool.getQueue().size()));
        }, 0, 1, TimeUnit.SECONDS);
    }


    private static void userParallel() {
        Long now = System.currentTimeMillis();
        //  ExecutorService executorService = Executors.newFixedThreadPool(count);
        IntStream.range(0, count).parallel().forEach(i -> {
            try {
                Thread.sleep(1000);
                System.out.println("userParallel执行后的时间：" + (System.currentTimeMillis() - now));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        System.out.println("userParallel执行总时间：" + (System.currentTimeMillis() - now));
    }

    private static void userExecutor() {
        Long now = System.currentTimeMillis();
        ExecutorService executorService = Executors.newFixedThreadPool(count);
        IntStream.range(0, count * 1000).forEach(i -> executorService.execute(() -> {
            try {
                Thread.sleep(1000);
                System.out.println(Thread.currentThread() + "userExecutor执行后的时间：" + (System.currentTimeMillis() - now));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }));
        System.out.println("userExecutor执行总时间：" + (System.currentTimeMillis() - now));
    }

}

class synchronizedClass {

    public void testA(int num) {
        System.out.println("测试A" + num);
    }

    public synchronized void testB(int num) throws InterruptedException {
        System.out.println("测试B" + num);
        Thread.sleep(2000);
        testA(num);
    }
}
